import sys
import time
import random
import queue  # 使用 Python 标准库的队列
from PySide6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, 
    QTextEdit, QLabel, QProgressBar, QGridLayout, QGroupBox
)
from PySide6.QtCore import (
    QThread, Signal, QMutex, QWaitCondition, Qt
)

class WorkerThread(QThread):
    # 定义信号：用于传递字符串消息、进度更新和结果
    message_signal = Signal(str)
    progress_signal = Signal(int)
    result_signal = Signal(dict)
    finished_signal = Signal()

    def __init__(self, thread_id, iterations, parent=None):
        super().__init__(parent)
        self.thread_id = thread_id
        self.iterations = iterations
        self._is_paused = False
        self._is_canceled = False
        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.queue = queue.Queue()  # 使用 Python 标准库的队列

    def run(self):
        self.message_signal.emit(f"线程 {self.thread_id} 已启动")
        
        total = 0
        for i in range(1, self.iterations + 1):
            # 检查是否取消
            if self._is_canceled:
                self.message_signal.emit(f"线程 {self.thread_id} 被取消")
                return
                
            # 检查是否暂停
            self.mutex.lock()
            if self._is_paused:
                self.message_signal.emit(f"线程 {self.thread_id} 已暂停")
                self.condition.wait(self.mutex)
            self.mutex.unlock()
            
            # 执行工作
            time.sleep(0.5)  # 模拟耗时操作
            value = random.randint(1, 100)
            total += value
            
            # 发送进度更新
            progress = int(i / self.iterations * 100)
            self.progress_signal.emit(progress)
            
            # 处理队列中的消息 - 非阻塞方式
            try:
                message = self.queue.get_nowait()
                self.message_signal.emit(f"线程 {self.thread_id} 收到消息: '{message}'")
            except queue.Empty:
                pass
        
        # 发送结果
        result = {
            "thread_id": self.thread_id,
            "iterations": self.iterations,
            "total": total,
            "average": total / self.iterations
        }
        self.result_signal.emit(result)
        self.finished_signal.emit()

    def pause(self):
        self.mutex.lock()
        self._is_paused = True
        self.mutex.unlock()

    def resume(self):
        self.mutex.lock()
        self._is_paused = False
        self.condition.wakeAll()
        self.mutex.unlock()

    def cancel(self):
        self._is_canceled = True
        self.resume()  # 确保线程可以退出

    def send_message(self, message):
        self.queue.put(message)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PySide6 多线程参数传递示例")
        self.setGeometry(100, 100, 800, 600)
        
        # 创建线程列表
        self.threads = []
        
        # 创建UI
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        layout = QVBoxLayout()
        self.central_widget.setLayout(layout)
        
        # 控制区域
        control_group = QGroupBox("线程控制")
        control_layout = QGridLayout()
        
        self.start_button = QPushButton("启动线程")
        self.start_button.clicked.connect(self.start_threads)
        control_layout.addWidget(self.start_button, 0, 0)
        
        self.pause_button = QPushButton("暂停所有线程")
        self.pause_button.clicked.connect(self.pause_threads)
        self.pause_button.setEnabled(False)
        control_layout.addWidget(self.pause_button, 0, 1)
        
        self.resume_button = QPushButton("恢复所有线程")
        self.resume_button.clicked.connect(self.resume_threads)
        self.resume_button.setEnabled(False)
        control_layout.addWidget(self.resume_button, 0, 2)
        
        self.cancel_button = QPushButton("取消所有线程")
        self.cancel_button.clicked.connect(self.cancel_threads)
        self.cancel_button.setEnabled(False)
        control_layout.addWidget(self.cancel_button, 0, 3)
        
        self.message_input = QTextEdit()
        self.message_input.setPlaceholderText("输入要发送给线程的消息...")
        self.message_input.setMaximumHeight(60)
        control_layout.addWidget(self.message_input, 1, 0, 1, 3)
        
        self.send_button = QPushButton("发送消息")
        self.send_button.clicked.connect(self.send_message_to_threads)
        control_layout.addWidget(self.send_button, 1, 3)
        
        control_group.setLayout(control_layout)
        layout.addWidget(control_group)
        
        # 线程状态区域
        self.status_group = QGroupBox("线程状态")
        self.status_layout = QGridLayout()
        self.status_group.setLayout(self.status_layout)
        layout.addWidget(self.status_group)
        
        # 日志区域
        self.log = QTextEdit()
        self.log.setReadOnly(True)
        layout.addWidget(QLabel("日志输出:"))
        layout.addWidget(self.log)
        
        # 添加状态标签
        self.status_labels = []
        self.progress_bars = []
        
        for i in range(3):
            label = QLabel(f"线程 {i+1}: 未启动")
            progress = QProgressBar()
            progress.setRange(0, 100)
            
            self.status_layout.addWidget(QLabel(f"线程 {i+1}:"), i, 0)
            self.status_layout.addWidget(label, i, 1)
            self.status_layout.addWidget(progress, i, 2)
            
            self.status_labels.append(label)
            self.progress_bars.append(progress)
    
    def start_threads(self):
        self.log.append("启动线程...")
        
        # 清除旧线程
        for thread in self.threads:
            if thread.isRunning():
                thread.cancel()
                thread.wait()
        
        self.threads = []
        
        # 创建并启动新线程，传递不同的参数
        for i in range(3):
            iterations = (i + 1) * 10  # 每个线程不同的迭代次数
            thread = WorkerThread(i+1, iterations)
            
            # 连接信号
            thread.message_signal.connect(self.log_message)
            thread.progress_signal.connect(lambda progress, idx=i: self.update_progress(idx, progress))
            thread.result_signal.connect(self.handle_result)
            thread.finished_signal.connect(lambda idx=i: self.thread_finished(idx))
            
            self.threads.append(thread)
            thread.start()
            self.status_labels[i].setText(f"线程 {i+1}: 运行中")
        
        # 更新按钮状态
        self.start_button.setEnabled(False)
        self.pause_button.setEnabled(True)
        self.resume_button.setEnabled(False)
        self.cancel_button.setEnabled(True)
    
    def pause_threads(self):
        self.log.append("暂停所有线程...")
        for thread in self.threads:
            thread.pause()
        self.pause_button.setEnabled(False)
        self.resume_button.setEnabled(True)
    
    def resume_threads(self):
        self.log.append("恢复所有线程...")
        for thread in self.threads:
            thread.resume()
        self.pause_button.setEnabled(True)
        self.resume_button.setEnabled(False)
    
    def cancel_threads(self):
        self.log.append("取消所有线程...")
        for thread in self.threads:
            thread.cancel()
        
        # 重置UI
        for i in range(3):
            self.status_labels[i].setText(f"线程 {i+1}: 已取消")
        
        self.start_button.setEnabled(True)
        self.pause_button.setEnabled(False)
        self.resume_button.setEnabled(False)
        self.cancel_button.setEnabled(False)
    
    def send_message_to_threads(self):
        message = self.message_input.toPlainText().strip()
        if message:
            self.log.append(f"向所有线程发送消息: '{message}'")
            for thread in self.threads:
                thread.send_message(message)
            self.message_input.clear()
    
    def log_message(self, message):
        self.log.append(message)
    
    def update_progress(self, thread_index, progress):
        self.progress_bars[thread_index].setValue(progress)
    
    def handle_result(self, result):
        thread_id = result["thread_id"]
        self.log.append(f"线程 {thread_id} 完成: "
                        f"迭代次数={result['iterations']}, "
                        f"总和={result['total']}, "
                        f"平均值={result['average']:.2f}")
    
    def thread_finished(self, thread_index):
        self.status_labels[thread_index].setText(f"线程 {thread_index+1}: 已完成")
        
        # 检查所有线程是否完成
        all_finished = all(not thread.isRunning() for thread in self.threads)
        if all_finished:
            self.start_button.setEnabled(True)
            self.pause_button.setEnabled(False)
            self.resume_button.setEnabled(False)
            self.cancel_button.setEnabled(False)
            self.log.append("所有线程已完成！")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    
    window = MainWindow()
    window.show()
    
    sys.exit(app.exec())